﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.IO;
using System.Drawing;
using System.Configuration;
using System.Data;
using System.Resources;
using System.Diagnostics;
using System.Text.RegularExpressions;

namespace MSBIHelper.Helper
{

    public class ParameterObject
    {
       public bool _isAdd{get;set;}
       public bool _isFolder { get;set;}
       public RichTextBox _rtb { get;set;}
       public string _varNameValue {get;set; }
       public string[] _fileNames { get;set;}
       public string _fileName {get;set; }
       public ParameterObject() { }
 
    }
 
    class Util
    {
      static  FolderBrowserDialog fbd1 = new FolderBrowserDialog();
      static  OpenFileDialog ofd1 = new OpenFileDialog();
      static  ManualResetEvent mreofd = new ManualResetEvent(false);
      static ResourceManager _rm = new ResourceManager(typeof(MyResource));

       public static string[] SelectFiles(bool isFolder)
        {
            object filenames = new string[] { };
            mreofd.Reset();
            Thread thread = new Thread(
                o =>
                {
                    if (isFolder)
                        getFolderFiles(ref filenames);
                    else
                        getFiles(ref filenames);
                }
                );
            thread.SetApartmentState(ApartmentState.STA);
            thread.Start();
            mreofd.WaitOne();
            return (string[])filenames;
        }

       static void getFolderFiles(ref Object obj)
        {
            string pkgfolder = string.Empty;
            if (fbd1.ShowDialog().Equals(DialogResult.OK))
            {
                pkgfolder = fbd1.SelectedPath;
                obj = Directory.GetFiles(pkgfolder, "*.dtsx", SearchOption.AllDirectories);
            }
            mreofd.Set();
        }

       static void getFiles(ref Object obj)
        {
            ofd1.Multiselect = true;
            if (ofd1.ShowDialog().Equals(DialogResult.OK))
            {
                obj = ofd1.FileNames;
            }
            mreofd.Set();
        }

       public static void work(bool isAdd, bool isFolder,RichTextBox rtbMsg,DoGoodJob dgj)
       {
           string[] filenames = SelectFiles(isFolder);
           if (filenames.Length == 0) return;
           Thread workThread = new Thread(e =>
           {
               ParallelHelper.ParallelDoJob(filenames, isAdd, rtbMsg,dgj);
           }
           );
           workThread.Name = "workThread";
           workThread.Priority = ThreadPriority.AboveNormal;
           workThread.Start();
       }

       public static void work(ParameterObject _po, DoGoodJob2 dgj)
       {
           _po._fileNames = SelectFiles(_po._isFolder);
           if (_po._fileNames.Length == 0) return;
           Thread workThread = new Thread(e =>
           { 
               ParallelHelper.ParallelDoJob(_po, dgj);
           }
           );
           workThread.Name = "workThread";
           workThread.Priority = ThreadPriority.AboveNormal;
           workThread.Start();
       }

       public static void HeightErrorFileList(RichTextBox rtb)
       {
            string Sstart = "Error files list:";
            string Send = "*********************************************************$";
            int start = rtb.Text.IndexOf(Sstart);
            int len = rtb.Text.IndexOf(Send) - start;
            rtb.Select(start, len);
            rtb.SelectionColor = Color.Red;
            rtb.SelectionFont = new Font(rtb.Font, rtb.Font.Style | FontStyle.Bold | FontStyle.Italic);
            rtb.SelectionBackColor = Color.Yellow;
       }


       public static DataTable GetAppSetting()
       {
           DataTable dt = new DataTable();
           dt.Columns.Add("Key");
           dt.Columns.Add("Value");
           Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
           AppSettingsSection AppSettingSec = config.AppSettings;
           foreach (KeyValueConfigurationElement item in AppSettingSec.Settings)
           {
               if (item.LockItem != true)
               {
                   DataRow dr = dt.NewRow();
                   dr[0] = item.Key;
                   dr[1] = item.Value;
                   dt.Rows.Add(dr);
               }
           }
           return dt;
       }

       public static void UpdateAppSetting(DataGridView dgv)
       {
           Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
           AppSettingsSection AppSettingSec = config.AppSettings;
           foreach (DataGridViewRow dgvr in dgv.Rows)
           {
               if (AppSettingSec.Settings[dgvr.Cells[0].Value.ToString()].Value != dgvr.Cells[1].Value.ToString())
                   AppSettingSec.Settings[dgvr.Cells[0].Value.ToString()].Value  = dgvr.Cells[1].Value.ToString();
           }
           ConfigurationManager.RefreshSection("appSettings");
           config.Save();
       }

       public static string GetAppSetting(string key)
       {
               return ConfigurationManager.AppSettings[key];
       }

       public static string GetStringFromResource(string sourceName)
       {
           return _rm.GetString(sourceName);
       }

       public static void GetUserManul()
       {
           string target = "http://www.kuaipan.cn/file/id_7224998280305156.htm";  

           try
           {
               System.Diagnostics.Process.Start(target);
           }
           catch
               (System.ComponentModel.Win32Exception noBrowser)
           {
               if (noBrowser.ErrorCode == -2147467259)
                   MessageBox.Show(noBrowser.Message);
           }
           catch (System.Exception other)
           {
               MessageBox.Show(other.Message);
           }
       }

       public static void Explorer(string path)
       {
           Process process = new Process
           {
               StartInfo = { FileName = "explorer.exe", Arguments = path }
           };
           process.Start();
           process.WaitForExit();
           process.Close();
       }

       public void GetFileCount(object para)
       {
           string path = para.ToString().Split(new char[] { ',' })[0];
           int pos = int.Parse(para.ToString().Split(new char[] { ',' })[1]);
           int num2 = int.Parse(para.ToString().Split(new char[] { ',' })[2]);
           int num3 = int.Parse(para.ToString().Split(new char[] { ',' })[3]);
           int num4 = 0;
           using (FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read))
           {
               int count = 0x100000 * num3;
               byte[] buffer = new byte[count];
               int num6 = 0;
               stream.Seek((long)pos, SeekOrigin.Begin);
               while (num2 > 0)
               {
                   num6 = stream.Read(buffer, 0, count);
                   num2 -= num6;
                   num4 += Regex.Matches(Encoding.UTF8.GetString(buffer), @"\n").Count;
                   Array.Clear(buffer, 0, buffer.Length - 1);
               }
               num4 += (GetLastByte(stream, pos) == 10) ? 0 : 1;
           }
           //this.TotalLineCount += num4;
           //string str2 = "current total row count： " + ((int)this.TotalLineCount) + Environment.NewLine;
           //this.SetMyTextBoxValue(this.txtCountMsg, str2);
       }

       public static byte GetLastByte(FileStream fs, int pos)
       {
           if (!fs.CanSeek)
           {
               throw new Exception("the filestream can not seek");
           }
           fs.Seek((long)-pos, SeekOrigin.End);
           return byte.Parse(fs.ReadByte().ToString());
       }


        /// </summary>
        /// <param name="filename">full path of the file</param>
        /// <param name="count">How many rows you want</param>
        /// <param name="type">0:top else:last</param>
        /// <returns></returns>
       public static string GetRowsOFFile(string filename,int count, int type)
       {
           try
           {
               Encoding encd = Encoding.Default;
               string type_str = (type.Equals(0) ? "Top_" : "Last_");
               using (StreamReader reader = new StreamReader(filename, true))
               {
                   encd = reader.CurrentEncoding;
               }

               int filecount = 0;  int counter = 0;
               string str = string.Empty; 
               //new file name and Create
               string  newFilePath = Path.GetDirectoryName(filename)
                   + "\\" + Path.GetFileNameWithoutExtension(filename)
                   + "_Demo_" + type_str
                   + count.ToString() 
                   + Path.GetExtension(filename);
                 
               if (type.Equals(0))//Get top n rows of files
               {
                  using( StreamWriter writer = new StreamWriter(newFilePath, false, encd))
                   {
                       using (StreamReader reader = new StreamReader(filename, encd))
                       {
                           while (((str = reader.ReadLine()) != null) && (counter++ < count))
                           {
                               writer.WriteLine(str);
                               writer.Flush();
                           }
                         }
                    }
               }
               #region archived
               //else if (reader.BaseStream.CanSeek)
               //{
               //    Stack<string> stack = new Stack<string>();
               //    reader.BaseStream.Seek(0L, SeekOrigin.End);
               //    //if (stream.Length.Equals(stream.Position))
               //    //{
               //    //    while (ReadByte(stream).Equals(10) || ReadByte(stream).Equals(13))
               //    //    {
               //    //        ReadByte(stream);
               //    //    }
               //    //    stream.Position += 2L;
               //    //}
               //    while (((str = ReadLine(stream,enc)) != null) && (num3++ < count))
               //    {
               //        stack.Push(str);
               //    }
               //    foreach (string str3 in stack)
               //    {
               //        writer.WriteLine(str3);
               //        writer.Flush();
               //    }
               //}
               #endregion
               else
               {
                   filecount = CountFileRowCount(filename);
                   if (count > filecount) return "count more than the file count";
                   
                   using (StreamWriter writer = new StreamWriter(newFilePath, false, encd))
                   {
                       using (StreamReader sr = new StreamReader(filename, encd))
                       {
                           while (counter++ < filecount - count)
                           {
                               sr.ReadLine();
                           }
                           while ((str = sr.ReadLine()) != null)
                           {
                               writer.WriteLine(str);
                               writer.Flush();
                           }
                       }
                   }
                 
               } 
               string msg = "Generate " + type_str + count.ToString()+ " rows for " + filename;
               return (msg);
           }
           catch (Exception exception)
           {
               return exception.Message;
           }
       }
 
       public static int CountFileRowCount(string filename)
       {
           int lineCount = 0;
           using (StreamReader reader = new StreamReader(File.Open(filename, FileMode.Open, FileAccess.Read)))
           {
               while (reader.ReadLine() != null)
               {
                   lineCount++;
               }
           }
           return lineCount;
       }
      
        static int ReadByte(FileStream fs)
       {
           int num = 0;
           if (0L >= fs.Position)
           {
               return -1;
           }
           fs.Position -= 1L;
           num = fs.ReadByte();
           fs.Position -= 1L;
           return num;
       }

        static string ReadLine(FileStream fs,Encoding enc)
       {
           Stack<byte> stack = new Stack<byte>();
           int num = ReadByte(fs);
           do
           {
               if (num.Equals(-1))
               {
                   break;
               }
               if (num.Equals(13))
               {
                   num = ReadByte(fs);
               }
               stack.Push((byte)num);
               num = ReadByte(fs);
           }
           while ((num != 10) && (fs.Position >= 0L));
           return ((stack.Count > 0) ? enc.GetString(stack.ToArray()) : null);
       }
 
    }
}
